home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / Genie / Projects / AEA / Source / Sources / Object Accessors / AEAAccessorModelFromWild.cc < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-24  |  5.6 KB  |  205 lines

  1. /*    ===========================
  2.  *    AEAAccessorModelFromWild.cc
  3.  *    ===========================
  4.  */
  5.  
  6. #include "AEADebugging.h"
  7.  
  8. #include "AEAModel.hh"
  9. #include "AEADescKeyData.hh"
  10. #include "AEADescList.hh"
  11. #include "AEAAccessorModelFromWild.hh"
  12. #include "AEATokenModel.hh"
  13.  
  14. AEAAccessorModelFromWild::AEAAccessorModelFromWild(DescType inDesiredClass, DescType inContainerType)
  15. : AEAAccessor(inDesiredClass, inContainerType)
  16. {
  17. }
  18.  
  19. AEAAccessorModelFromWild::AEAAccessorModelFromWild()
  20. : AEAAccessor(typeModelToken, typeModelToken)
  21. {
  22. }
  23.  
  24. AEAAccessorModelFromWild::~AEAAccessorModelFromWild()
  25. {
  26. }
  27.  
  28. void
  29. AEAAccessorModelFromWild::AccessObject(DescType inDesiredClass, 
  30.     const AEAModelContainer *inContainer, DescType inContainerClass, 
  31.     DescType inKeyForm, const AEADescKeyData &inKeyData, AEAModel *&outObject) const
  32. {
  33.     // Get the containing object
  34.     // Get the selection data
  35.     switch (inKeyForm) {
  36.         case formPropertyID:
  37.             AccessObjectByPropertyID(inDesiredClass, inContainer, inContainerClass, 
  38.                 inKeyData, outObject);
  39.             break;
  40.         case formName:
  41.             AccessObjectByName(inDesiredClass, inContainer, inContainerClass, 
  42.                 inKeyData, outObject);
  43.             break;
  44.         case formAbsolutePosition:
  45.             AccessObjectByAbsolutePosition(inDesiredClass, 
  46.                 inContainer, inContainerClass, inKeyData, outObject);
  47.             break;        
  48.         default:
  49.             throw errAEEventNotHandled;
  50.             break;
  51.     }
  52.  
  53. }
  54.  
  55. void
  56. AEAAccessorModelFromWild::AccessObjectByPropertyID(DescType inDesiredClass, 
  57.     const AEAModelContainer *inContainer, DescType inContainerClass, 
  58.     const AEADescKeyData &inKeyData, AEAModel *&outObject) const
  59. {
  60.     //ThrowOSErr_(errAEEventNotHandled);
  61.     DescType prop;
  62.     inKeyData.Get(prop);
  63.     inContainer->GetProperty(inDesiredClass, prop, outObject);
  64. }
  65.  
  66. void
  67. AEAAccessorModelFromWild::AccessObjectByName(DescType inDesiredClass, 
  68.     const AEAModelContainer *inContainer, DescType inContainerClass, 
  69.     const AEADescKeyData &inKeyData, AEAModel *&outObject) const
  70. {
  71.     ThrowIfNULL_(inContainer);
  72.     
  73. #if 0
  74.     AEADesc name;
  75.     inKeyData.Get(name);
  76. #endif    
  77.     inContainer->GetElementByName(inDesiredClass, inKeyData, outObject);
  78.     
  79.     if (outObject == NULL)
  80.         ThrowOSErr_(errAENoSuchObject);
  81. }
  82.  
  83. #if 0
  84. void
  85. AEAAccessorModelFromWild::AccessObjectByName(DescType inDesiredClass, 
  86.     const AEAModelContainer *inContainer, DescType inContainerClass, 
  87.     const AEADescKeyData &inKeyData, AEAModel *&outObject) const
  88. {
  89.     ThrowOSErr_(errAEEventNotHandled);
  90. }
  91. #endif
  92.  
  93. void
  94. AEAAccessorModelFromWild::AccessObjectByAbsolutePosition(DescType inDesiredClass, 
  95.     const AEAModelContainer *inContainer, DescType inContainerClass, 
  96.     const AEADescKeyData &inKeyData, AEAModel *&outObject) const
  97. {
  98.     ThrowIfNULL_(inContainer);
  99.     
  100.     long count = inContainer->CountElements(inDesiredClass);
  101.     long index = 0;
  102.     DescType position = typeNull;
  103.     AEAModel *obj = NULL;
  104.     
  105.     if (inKeyData.DescriptorType() == typeAbsoluteOrdinal) {
  106.         inKeyData.Get(position);
  107.         switch (position) {
  108.             case kAEAny: // Fix it later.
  109.             case kAEFirst:
  110.                 index = 1;
  111.                 break;
  112.             case kAELast:
  113.                 index = count;
  114.                 break;
  115.             case kAEMiddle:
  116.                 index = (count + 1) / 2;
  117.                 break;
  118.             default:
  119.                 index = 0;
  120.                 break;
  121.         }
  122.     } else {
  123.         if (inKeyData.DescriptorType() == typeLongInteger) {
  124.             inKeyData.Get(index);
  125.         } else if (inKeyData.DescriptorType() == typeShortInteger) {
  126.             inKeyData.Get(index);
  127.         }
  128.         if (index < 0)
  129.             index = count + 1 - index;
  130.     }
  131.     if (index > 0) {
  132.         inContainer->GetElementByIndex(inDesiredClass, index, outObject);
  133.         //instance = app->Instance(index);
  134.         //if (obj == NULL) ThrowOSErr_(errAENoSuchObject);
  135.         //outObject = obj;
  136.     } else if (position == kAEAll) {
  137.         // make list
  138.         AEDesc tokenList;
  139.         AEADescList list;
  140.         //AEADesc::AssignDesc(&list, &tokenList);
  141.         // list.Ref() = tokenList;  // This can't be right... (unititialized)
  142.         list.Create();
  143.         // On exception, dispose of the list descriptor's data handle.
  144.         //list.SetDestruction(true, false);
  145.         for (int i = 1; i <= count; i++) {
  146.             inContainer->GetElementByIndex(inDesiredClass, i, obj);
  147.             if (obj != NULL) {
  148.                 AEATokenModel *token;
  149.                 obj->MakeToken(token);
  150.                 list.Put(i, typeModelToken, &token, sizeof token);
  151.             }
  152.         }
  153.         // If we got this far, we need the data handle.
  154.         //list.SetDestruction(false, false);
  155.         tokenList = list.Ref();
  156.         list.Reset();
  157.         // Yes!  We are *throwing* the list as an exception!
  158.         throw tokenList;
  159.     } else
  160.         ThrowOSErr_(errAENoSuchObject);
  161. }
  162.  
  163.  
  164. /*
  165.  */
  166.  
  167. void
  168. AEAAccessorModelFromWild::AccessObject(
  169.     DescType inDesiredClass, const AEDesc *inContainerToken, DescType inContainerClass, 
  170.     DescType inKeyForm, const AEDesc *inKeyData, AEDesc *outToken) const
  171. {
  172.     // What should we do if the descriptor type is wrong? Could it even be?
  173.     if (inContainerToken->descriptorType != typeModelToken)
  174.         ThrowOSErr_(errAEWrongDataType);
  175.     // The data handle contains a pointer to the token object.
  176.     AEATokenModel *token = **(AEATokenModel ***)inContainerToken->dataHandle;
  177.     // This shouldn't happen, but check anyway.
  178.     ThrowIfNULL_(token);
  179.  
  180.     AEAModelContainer *container = token->Model();
  181.     const AEADescKeyData keyData(*inKeyData);
  182.     AEAModel *obj;
  183.     try {
  184.         // If we're accessing a list, then an AEDesc exception will be thrown.
  185.         AccessObject(inDesiredClass, container, inContainerClass, inKeyForm, keyData, obj);
  186.         // obj now exists. It could be a temp, so be sure it gets a goodbye kiss.
  187.         try {
  188.             AEATokenModel *token;
  189.             obj->MakeToken(token);
  190.             // token now exists (and is responsible for obj). Delete on exception.
  191.             OSErr err = ::AECreateDesc(typeModelToken, &token, sizeof token, outToken);
  192.             if (err) {
  193.                 delete token;
  194.                 ThrowOSErr_(err);
  195.             }
  196.         } catch (...) {
  197.             obj->KissGoodbye();
  198.             throw;
  199.         }
  200.     } catch (AEDesc desc) {
  201.         // the key data specified a list of model objects.
  202.         *outToken = desc;
  203.     }
  204. }
  205.